﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using GuildStock.Models;
using GuildStock.Services.Blizzard;
using GuildStock.Services.JsonToDynamic;

namespace GuildStock.Services
{
  /// <summary>
  /// Realm processing logic.
  /// </summary>
  public class RealmProcessor
  {
    private static IEnumerable<Zones> ZonesList = Enum.GetValues(typeof(Zones)).Cast<Zones>();

    private delegate void UpdateRealmsDelegate();

    /// <summary>
    /// Update realm data base async.
    /// </summary>
    public static void UpdateRealmsAsync()
    {
      new UpdateRealmsDelegate(RealmProcessor.UpdateRealms).BeginInvoke(null, null);
    }

    /// <summary>
    /// Update realm data base.
    /// </summary>
    public static void UpdateRealms()
    {
      var context = new GuildStockDataDataContext();
      var realms = context.Realms.ToList();

      Exception firstException = null;

      foreach (var zone in ZonesList)
      {
        try
        {
          var realmsJson = new BlizzardService().GetRealmStatus(zone);
          var realmsList = JsonHelper.ConvertJsonToDynamic(realmsJson);
          if (realmsList != null && realmsList.realms != null)
          {
            var list = new List<Realm>();
            foreach (dynamic realmInfo in realmsList.realms)
            {
              var name = realmInfo.name;
              var type = realmInfo.type;

              if (!realms.Any(r => r.Name == name))
              {
                var realm = new Realm();
                realm.Name = name;
                realm.Type = type;
                realm.Zone = zone.ToString();
                list.Add(realm);
              }
            }

            context.Realms.InsertAllOnSubmit(list);
            context.SubmitChanges();
          }
        }
        catch(Exception ex)
        {
          // Save exception and try to update other zones.
          if (firstException == null) 
          {
            firstException = ex; 
          }
        }
      }

      if (firstException != null)
      {
        throw firstException;
      }
    }
  }
}